package com.keyou.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.keyou.reggie.common.CustomException;
import com.keyou.reggie.dto.DishDTO;
import com.keyou.reggie.entity.Dish;
import com.keyou.reggie.entity.DishFlavor;
import com.keyou.reggie.entity.SetMeal;
import com.keyou.reggie.entity.SetmealDish;
import com.keyou.reggie.mapper.DishMapper;
import com.keyou.reggie.service.DishFlavorService;
import com.keyou.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: klq
 * @Date: 2023/1/10 16:46
 * @Description:
 */

/**
 * 按照入栈的顺序，最先进入的是子类的构造函数，然后才是邻近的父类构造函数，最后再栈顶的是最终的父类构造函数
 * 从本质上讲，this 是一个指向本对象的指针, 然而 super 是一个 Java 关键字。
 * <p>
 * super()与this()的区别主要有以下：
 * 不同点：
 * 1、super()主要是对父类构造函数的调用，this()是对重载构造函数的调用
 * 2、super()主要是在继承了父类的子类的构造函数中使用，是在不同类中的使用；this()主要是在同一类的不同构造函数中的使用
 * 相同点：
 * 1、super()和this()都必须在构造函数的第一行进行调用，否则就是错误的
 */
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     * 保存菜品（带口味）
     *
     * @param dishDto
     */
    @Override
    public void saveWithFlavor(DishDTO dishDto) {
        //先将菜品数据保存到dish表
        this.save(dishDto);
        //获取dishId
        Long dishId = dishDto.getId();
        //将获取到的dishId赋值给dishFlavor的dishId属性
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishId);
        }
        //同时将菜品口味数据保存到dish_flavor表
        dishFlavorService.saveBatch(flavors);
    }

    /**
     * 根据dishId获取具体菜品信息
     *
     * @param dishId
     * @return
     */
    @Override
    public DishDTO getDishByIdWithFlavor(Long dishId) {
        //先根据id查询到对应的dish对象
        Dish dish = this.getById(dishId);

        //创建一个dishDao对象
        DishDTO dishDto = new DishDTO();
        BeanUtils.copyProperties(dish, dishDto);

        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dishId);
        List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);

        //将其赋给dishDto
        dishDto.setFlavors(flavors);
        return dishDto;
    }

    /**
     * 修改菜品（先删除原本关联的口味，再重新导入）
     *
     * @param dishDTO
     */
    @Override
    @Transactional
    public void updateWithFlavor(DishDTO dishDTO) {
        //先更新当前菜品信息（dish表）
        this.updateById(dishDTO);

        //下面是更新当前菜品的口味数据（dish_flavor表）
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, dishDTO.getId());
        //先删除flavor数据
        dishFlavorService.remove(queryWrapper);

        //获取传入的新的口味数据
        List<DishFlavor> flavors = dishDTO.getFlavors();
        //这些口味数据还是没有dish_id，所以需要赋予其dishId
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishDTO.getId());
            return item;
        }).collect(Collectors.toList());
        //再重新加入到表中
        dishFlavorService.saveBatch(flavors);
    }

    @Override
    @Transactional
    public void deleteWithflavor(List<Long> ids) {
        //先判断一下能不能删，如果status为1，则菜品在售，不能删
        LambdaQueryWrapper<Dish> dishLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishLambdaQueryWrapper.in(Dish::getId, ids);
        dishLambdaQueryWrapper.eq(Dish::getStatus, 1);
        long count = this.count(dishLambdaQueryWrapper);
        if (count > 0) {
            throw new CustomException("菜品正在售卖中，请先停售再进行删除");
        }
        //删除菜品数据
        this.removeBatchByIds(ids);
        //继续删除菜品关联的口味数据
        LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        dishFlavorLambdaQueryWrapper.in(DishFlavor::getDishId, ids);
        dishFlavorService.remove(dishFlavorLambdaQueryWrapper);
    }

}